/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Contributors:  Mathias Bogaert

package soft.ay.qram.helpers;

import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import soft.ay.qram.DataSource;

/**
 * 此监控类，主要是为了防止缓存文件被删除的情况发生。<br>
 */
public class FileWatchdog extends Thread
{
    Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * The default delay between every file modification check, set to 60
     * seconds.
     */
    static final public long DEFAULT_DELAY = 60000;

    // 属性部分
    private final String DB_FILE = "cache.db";
    private final String[] TABLE_LIST = { "kv_table", "kv_time_table" };
    private final String TABLE_EXIST = "select count(*) from sqlite_master where type='table' and name = '%s'";
    private final String[] DDL_TABLES = { "CREATE TABLE kv_table" + " (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
                                          + "  string_key TEXT NOT NULL, "
                                          + "  string_value TEXT NOT NULL)",
                                          "CREATE TABLE kv_time_table" + " (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
                                                                             + "  string_key TEXT NOT NULL,"
                                                                             + "  string_value TEXT NOT NULL,"
                                                                             + "  expire_time NUMERIC NOT NULL)" };

    protected void checkAndConfigure() throws SQLException
    {
        // 数据库信息
        Connection connection = null;
        Statement statement = null;
        // 初始化标记
        boolean inited = false;
        try
        {
            // dbfile文件检查
            File dbFile = new File(DB_FILE);
            connection = null;
            if (dbFile.exists())
            {
                // 存在dbfile
                // 1、检查表是否存在
                Class.forName("org.sqlite.JDBC");
                connection = DriverManager.getConnection("jdbc:sqlite:cache.db");
                statement = connection.createStatement();
                ResultSet whetherExist = null;
                Integer existCount = null;
                for (int i = 0; i < TABLE_LIST.length; i++)
                {
                    whetherExist = statement.executeQuery(String.format(TABLE_EXIST, TABLE_LIST[i]));
                    if (whetherExist.next())
                    {
                        existCount = whetherExist.getInt(1);
                        if (existCount == null || existCount.intValue() == 0)
                        {
                            // 表不存在,新建
                            inited = createTable(connection, DDL_TABLES[i]);

                        } // endif
                    } // endif
                } // endfor
            }
            else
            {
                // 不存在
                Class.forName("org.sqlite.JDBC");
                connection = DriverManager.getConnection("jdbc:sqlite:cache.db");
                for (String eachT : DDL_TABLES)
                {
                    inited = createTable(connection, eachT);
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            // 关闭资源
            if (statement != null)
            {
                statement.close();
            }
            if (connection != null)
            {
                connection.close();
            }
            // 只要inited==true说明都经过了初始化动作
            if (inited)
            {
                // 重置datasource
                DataSource.getInstance().resetDataSource();
            }
        }

    }

    private boolean createTable(Connection connection, String table) throws SQLException
    {
        // 执行初始化
        Statement ddlStatement = connection.createStatement();
        ddlStatement.execute(table);
        // 关闭资源
        if (ddlStatement != null)
        {
            ddlStatement.close();
        }
        return true;
    }
    public void run()
    {
        while (true)
        {
            logger.info("FileWatchdog thread is running********");
            try
            {
                checkAndConfigure();
                TimeUnit.SECONDS.sleep(60);
            }
            catch (InterruptedException e)
            {
                logger.warn("thread is interupt");
                e.printStackTrace();
            }
            catch (SQLException e)
            {
                logger.error("Was not allowed to read check file existance, file:[" + DB_FILE + "].");
                e.printStackTrace();
            }
        }
    }
}
